home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
mxutil
/
dtcd101
/
dtcd.asm
< prev
next >
Wrap
Assembly Source File
|
1994-01-25
|
38KB
|
826 lines
Code Segment
Assume Cs:Code,Ds:Code
Org 100h
.286
;====---- Some constants for the scan-codes ----============================
ReleasedALT EQU 0B8h ;(Scan-code of ALT) OR 80h
KeyF11 EQU 57h ;F11 scan-code
KeyF12 EQU KeyF11+1 ;IMPORTANT!
KeyVolumeDown EQU 33h ;'<'
KeyVolumeUp EQU KeyVolumeDown+1 ;IMPORTANT!
;====---- Some global constants ----========================================
KeyboardFlags EQU 17h ;Keyboard-state bits
ALTNumericBuf EQU 19h ;Buffer for ALT-numeric
VolumeSteps EQU 5 ;Inc/Dec volume by step
Done EQU 100h ;Bit indicating done
DeviceBusy EQU 200h ;Bit indicating device busy
ErrorBit EQU 8000h ;Bit indicating IOCTL-Error
MaxBlockLen EQU 9 ;MaxLen of IOCTL-Block
;=============================================================================
Start:
Jmp Initialization
TSR Proc Far
Cmp Ah,4Fh ;Right sub-function?
Jz Popup ;Yes -> popup
CallOrgInt:
Jmp DWord Ptr CS:[OrgIntOfs] ;No -> original interrupt
Popup:
Push Bp ;Save regs...
Mov Bp,Sp
Push Ds
Push Es
Pusha
Push Cs
Pop Ds
Cmp Bx,'DT' ;Installation check
Jnz NoInitCheck
Cmp Cx,'CD'
Jnz NoInitCheck
Popa
Mov Ax,'Yo' ;Return 'Yo'...
Jmp ReturnAfterInitCheck ;and return
NoInitCheck:
Push 40h ;Set ES to BIOS Data Segment
Pop Es
Cmp Al,ReleasedALT ;ALT-key released?
Jz JumpRequest ;Yes -> check for jump-req.
Test Al,80h ;Any other released key ?
Jnz ReturnFromPopup ;Released -> exit
CheckForF11:
Cmp Al,KeyF11 ;F11 pressed
Jz PlayControl ;Yes -> PlayControl
Cmp Al,KeyF12 ;F12 pressed
Jz PlayControl ;Yes -> Playcontrol
Cmp Al,KeyVolumeDown ;'<' pressed
Jz VolumeControl ;Yes -> Volumecontrol
Cmp Al,KeyVolumeUp ;'>' pressed
Jz VolumeControl ;Yes -> Volumecontrol
Jmp ReturnFromPopup
JumpRequest:
Mov Al,ES:[KeyboardFlags] ;Get keyboard flags
And Al,3 ;Check if a shift is pressed
Jz ReturnFromPopup ;No -> exit
Call JumpToTrack ;Perform JumpRequest
Jmp ReturnFromPopup ;No carry-clear after this!
PlayControl:
Sub Al,KeyF11 ;F11 -> AL=0, F12 -> AL=1
Mov Si,Offset RequestNumber ;Array with request offsets
Jmp HandleKey
VolumeControl:
Sub Al,KeyVolumeDown ;'<' -> AL=0, '>' -> AL=1
Mov Si,Offset VolumeRequest ;Array with request offsets
HandleKey:
Sub Bh,Bh ;Clear BH
Mov Bl,ES:[KeyboardFlags] ;Get keyboard bits in BL
And Bl,15 ;Filter CTRL/ALT/SHIFT-keys
Mov Ah,[Si+Bx] ;Get request number in AH
Or Ah,Ah ;Request 0 ?
Jz ReturnFromPopup ;Yes -> No request, exit
Dec Ah ;Calc appropriate function
Mov Bl,Ah
Add Bl,Al
Shl Bx,1
Push Cs ;Set ES to CS
Pop Es
Cmp [Busy],1 ;Already busy?
Jz DontDoRequest ;Yes -> don't interfere
Mov [Busy],1 ;Set busy flag
Call [RequestHandlr+Bx] ;Call request-handler
Mov [Busy],0 ;Clear busy flag
DontDoRequest:
And Word Ptr [Bp+6],0FFFEh ;Clear original carry-flag
ReturnFromPopup:
Popa ;Pop registers
ReturnAfterInitCheck:
Pop Es ;Exit...
Pop Ds
Pop Bp
Iret
Endp
PrepareIOCTL Proc Near ;Setup variables for IOCTL
Mov [IOCTLBlockLen],14h ;See CDROM.LST for details
Mov [IOCTLTransOfs],Offset IOCTLBuffer
Mov [IOCTLTransSeg],Ds
Mov [IOCTLLen],Cx
Mov Bx,Offset IOCTLBlock
Mov Ax,1510h
Mov Cx,[CDROMDrive]
Ret
Endp
IOCTLOutput Proc Near
Call PrepareIOCTL ;Setup IOCTL variables
Mov [IOCTLCommand],0Ch ;Output command
TryOutputAgain:
Int 2Fh ;Perform IOCTL-output
Test [IOCTLStatus],Done ;Request ok ?
Jz TryOutputAgain ;No -> try again
Ret
Endp
IOCTLInput Proc Near
Call PrepareIOCTL ;Setup IOCTL variables
Mov [IOCTLCommand],3 ;Input command
TryInputAgain:
Int 2Fh ;Perform IOCTL-input
Test [IOCTLStatus],Done ;Request ok ?
Jz TryInputAgain ;No -> try again
Ret
Endp
DirectCommand Proc Near ;Send a direct command...
Mov Ax,1510h
Mov Bx,Offset IOCTLBlock
Mov Cx,[CDROMDrive]
Int 2Fh
Ret
Endp
RedBookToHSG Proc Near ;In: DS:[SI]=Red Book sector
Push Bx ;Out: DX:AX=HSG sector
Push Cx
Mov Al,75
Mul Byte Ptr [Si+1]
Mov Bx,Ax
Sub Ah,Ah
Mov Al,[Si+2]
Mov Cx,4500
Mul Cx
Add Ax,Bx
Adc Dx,0
Add Al,[Si]
Adc Ah,0
Adc Dx,0
Sub Ax,150
Sbb Dx,0
Pop Cx
Pop Bx
Ret
Endp
SaveCurPos Proc Near ;Saves drive-head position
Mov [IOCTLBuffer],1 ;CD-ROM request 1
Mov [IOCTLBuffer+1],0 ;HSG addressing
Mov Cx,6 ;Expects 6 bytes
Call IOCTLInput ;Get the input
Mov Ax,Word Ptr [IOCTLBuffer+2] ;Copy to HSGINDEX
Mov Word Ptr [HSGIndex],Ax
Mov Ax,Word Ptr [IOCTLBuffer+4]
Mov Word Ptr [HSGIndex+2],Ax
Ret
Endp
GetCDInfo Proc Near ;Gets CD information
Mov [IOCTLBuffer],0Ah ;CD-ROM request 10
Mov Cx,7 ;Expects 7 bytes
Call IOCTLInput ;Get the input
Test [IOCTLStatus],ErrorBit ;Error occured ?
Jnz ExitGetInfo ;Yes -> exit procedure
Mov Al,[IOCTLBuffer+1] ;Copy data from buffer
Mov [MinTrack],Al
Mov Al,[IOCTLBuffer+2]
Mov [MaxTrack],Al
Mov Si,Offset IOCTLBuffer+3
Call RedBookToHSG ;Convert last sector
Mov Word Ptr [MaxIndex],Ax ;Save as last audio-sector
Mov Word Ptr [MaxIndex+2],Dx
Mov Cl,[MinTrack]
Call GetTrackInfo ;Get info of the first track
Mov Si,Offset IOCTLBuffer+2
Call RedBookToHSG ;Convert starting sector
Mov Word Ptr [MinIndex],Ax ;Save as first audio-sector
Mov Word Ptr [MinIndex+2],Dx
ExitGetInfo:
Ret
Endp
CDLoaded Proc Near ;Returns: ZF=0 if CD loaded
Mov [IOCTLBuffer],6 ;CD-ROM request 6
Mov Cx,5 ;Expects 5 bytes
Call IOCTLInput ;Get the input
Test Word Ptr [IOCTLBuffer+1],1 ;Filter data
Ret
Endp
GetTrackInfo Proc Near ;Returns track info in buffer
Mov [IOCTLBuffer],0Bh ;CD-ROM request 11
Mov [IOCTLBuffer+1],Cl ;Info on track CL
Mov Cx,8 ;Expects 8 bytes
Call IOCTLInput ;Get the input
Ret
Endp
GetCurTrack Proc Near ;Returns: CL=current track
Call SaveCurPos ;Save current position
GetCurTrackFromIndex: ;External entry...
Mov Cl,[MinTrack] ;Setup vars before loop
Dec Cl ; (CL=MinTrack-1)
WalkToTrackLoop:
Inc Cl ;Increase track number
Cmp Cl,[MaxTrack] ;Is it bigger than MaxTrack
Ja DecreaseTrack ;Yes -> exit loop
Push Cx ;Save track number
Call GetTrackInfo ;Get track info
Pop Cx ;Restore track number
Mov Si,Offset IOCTLBuffer+2 ;Calc start sector of track
Call RedBookToHSG ;Calc...
Mov Si,Offset HSGIndex ;Compare to current position
Call CompareIndexes ;Compare...
Jb WalkToTrackLoop ;If below, repeat loop
DecreaseTrack:
Dec Cl ;Decrease track number
Ret
Endp
GetVolumeSettings Proc Near ;Get vol.settings in buffer
Mov [IOCTLBuffer],4 ;CD-ROM request 4
Mov Cx,9 ;Expects 9 bytes
Call IOCTLInput ;Get the input
Ret
Endp
SetVolumeSettings Proc Near ;Set vol.settings from buffer
Mov [IOCTLBuffer],3 ;CD-ROM request 3
Mov Cx,9 ;Expects 9 bytes
Call IOCTLOutput ;Write the output
Ret
Endp
PlayFromTrack Proc Near ;Plays from track to the end
Call GetTrackInfo ;Get the track info
Mov Si,Offset IOCTLBuffer+2 ;Convert to HSG-indexing
Call RedBookToHSG
Mov Word Ptr [HSGIndex],Ax ;Save as sector to start play
Mov Word Ptr [HSGIndex+2],Dx
Call PlayCD ;Play
Ret
Endp
IsAudioTrack Proc Near ;Returns: ZF=0 if audio-track
Call GetTrackInfo ;Get the track info
Mov Al,[IOCTLBuffer+6] ;Get track-bits in AL
And Al,50h ;Filter audio-bits
Jz AudioTrack ;Jump if audio-track
Cmp Al,10h ;Another posibility
Jz AudioTrack ;Jump if audio-track
NoAudioTrack:
Mov Al,1 ;Return ZF=1...
AudioTrack:
And Al,1 ;Set the zero-flag
Ret
Endp
GetNextAudioTrack Proc Near ;Returns: CL=next audio-track
Or Cl,Cl ;Is CL 0 ?
Jnz CheckNextFromHere ;No -> don't initialize
Mov Cl,[MinTrack] ;Set CL to (MinTrack-1)
Dec Cl
CheckNextFromHere:
Inc Cl ;Increase track number
Cmp Cl,[MaxTrack] ;Is it bigger than MaxTrack
Ja NoNextTrackFound ;Yes -> exit
Push Cx ;Save track number
Call IsAudioTrack ;Is it an audio-track ?
Pop Cx ;Restore track number
Jnz CheckNextFromHere ;No -> check next track
Jmp NextAudioTrackFound ;Audio track found...
NoNextTrackFound:
Sub Cl,Cl ;Return 0 (no more tracks)
NextAudioTrackFound:
Ret
Endp
GetPrevAudioTrack Proc Near ;Returns: CL=prev audio-track
Or Cl,Cl ;Is CL 0 ?
Jnz CheckPrevFromHere ;No -> don't initialize
Mov Cl,[MaxTrack] ;Set CL to (MaxTrack+1)
Inc Cl
CheckPrevFromHere:
Dec Cl ;Decrease track number
Cmp Cl,[MinTrack] ;Is it smaller than MinTrack
Jb NoPrevTrackFound ;Yes -> exit
Push Cx ;Save track number
Call IsAudioTrack ;Is it an audio-track ?
Pop Cx ;Restore track number
Jnz CheckPrevFromHere ;No -> check prev track
Jmp PrevAudioTrackFound ;Audio track found...
NoPrevTrackFound:
Sub Cl,Cl ;Return 0 (no more tracks)
PrevAudioTrackFound:
Ret
Endp
CompareIndexes Proc Near ;Compares DX:AX to [SI]
Cmp Dx,[Si+2] ;Is DX equal to [SI+2]
Jne EndOfComparison ;No -> exit (flags correct)
Cmp Ax,[Si] ;Compare AX to [SI]
EndOfComparison:
Ret ;(Flags updated)
Endp
JumpToTrack Proc Near ;Play directly from track
Push Es ;Save BIOS Data Segment
Push Cs ;Set ES to CS
Pop Es
Call GetCDInfo ;Get CD info
Pop Es ;Restore BIOS Data Segment
Sub Cl,Cl ;Set 0 in ALT-Num buffer,
Xchg Cl,ES:[ALTNumericBuf] ;and set CL to track-number
Cmp Cl,[MinTrack] ;Is it smaller than MinTrack
Jb ExitJumpToTrack ;Yes -> don't jump...
Cmp Cl,[MaxTrack] ;Is it bigger than MaxTrack
Ja ExitJumpToTrack ;Yes -> don't jump
Push Cx ;Save track number
Call IsAudioTrack ;Is it an audio-track
Pop Cx ;Restore track number
Jnz ExitJumpToTrack ;No -> exit
Push Cs ;Set ES to CS
Pop Es
Call PlayFromTrack ;Play from track...
ExitJumpToTrack:
Ret
Endp
UnlockDoor Proc Near ;Unlocks the drive door
Mov [IOCTLBuffer],1 ;CD-ROM request 1
Mov [IOCTLBuffer+1],0 ;0=Unlock door (1=Lock)
Mov Cx,2 ;Expects 2 bytes
Call IOCTLOutput ;Write the output
Ret
Endp
EjectCD Proc Near ;Ejects the CD
Call StopCD ;First stop playing
Call UnlockDoor ;Then unlock door
Mov [IOCTLBuffer],0 ;CD-ROM request 0
Mov Cx,1 ;Expects 1 byte
Call IOCTLOutput ;Write the output
Ret
Endp
LoadCD Proc Near ;Closes the drive door
Call CDLoaded ;Is CD already loaded ?
Jz ExitLoadCD ;Yes -> exit
Mov [IOCTLBuffer],5 ;CD-ROM request 5
Mov Cx,1 ;Expects 1 byte
Call IOCTLOutput ;Write the output
ExitLoadCD:
Ret
Endp
StopCD Proc Near ;Stop playing ('pause')
Push Word Ptr [HSGIndex] ;Save index
Push Word Ptr [HSGIndex+2]
Call SaveCurPos ;Get current position
Test [IOCTLStatus],DeviceBusy ;Is audio playing ?
Jz RestartCD ;No -> restart CD
Mov [IOCTLCommand],85h ;IOCTL request 133
Mov [IOCTLBlockLen],0Dh ;Set IOCTL blocklength
Call DirectCommand ;Execute a direct command
Mov Ax,Word Ptr [HSGIndex] ;Save index in restartaddress
Mov Word Ptr [StartAddress],Ax
Mov Ax,Word Ptr [HSGIndex+2]
Mov Word Ptr [StartAddress+2],Ax
Jmp ExitStopCD ;Leave procedure
RestartCD:
Mov Word Ptr [StartAddress],0 ;Set start index to 0
Mov Word Ptr [StartAddress+2],0 ; (play from first track)
ExitStopCD:
Pop Word Ptr [HSGIndex+2] ;Restore original index
Pop Word Ptr [HSGIndex]
Ret
Endp
PlayCD Proc Near ;Play CD from [HSGINDEX]
Call StopCD ;Stop CD first
Mov Si,Offset HSGIndex ;Copy sectors into buffer
Mov Ax,Word Ptr [HSGIndex]
Mov Word Ptr [CDStartPlay],Ax
Mov Ax,Word Ptr [HSGIndex+2]
Mov Word Ptr [CDStartPlay+2],Ax
Mov Ax,Word Ptr [MaxIndex] ;To the last audio-sector
Mov Dx,Word Ptr [MaxIndex+2]
Sub Ax,[Si] ;Subtract the starting sector
Sbb Dx,[Si+2]
Mov Word Ptr [CDStopPlay],Ax ;Set the number of sectors
Mov Word Ptr [CDStopPlay+2],Dx ; to play
Mov [IOCTLCommand],84h ;IOCTL request 132
Mov [IOCTLBlockLen],16h ;Set IOCTL blocklength
Call DirectCommand ;Execute a direct command
Mov Word Ptr [StartAddress],0 ;Reset the start address
Mov Word Ptr [StartAddress+2],0
Ret
Endp
PrevTrack Proc Near ;Jumps a track backwards
Call GetCDInfo ;Get CD info
Call GetCurTrack ;Get the current track
Call GetPrevAudioTrack ;Get the previous track
Or Cl,Cl ;Track found ?
Jz AtFirstAudioTrack ;No -> exit
Call PlayFromTrack ;Play from track...
AtFirstAudioTrack:
Ret
Endp
NextTrack Proc Near ;Jumps a track forward
Call GetCDInfo ;Get CD info
Call GetCurTrack ;Get the current track
Call GetNextAudioTrack ;Get the next track
Or Cl,Cl ;Track found ?
Jz AtLastAudioTrack ;No -> exit
Call PlayFromTrack ;Play from track...
AtLastAudioTrack:
Ret
Endp
Skip10Sex Proc Near ;Jump 10 seconds forward
Call GetCDInfo ;Get CD info
Call SaveCurPos ;Save current position
Mov Ax,Word Ptr [HSGIndex] ;Check if sector ok...
Mov Dx,Word Ptr [HSGIndex+2]
Add Ax,750 ;Add 750 frames=10 secs
Adc Dx,0
Mov Si,Offset MaxIndex
Call CompareIndexes ;Compare to MaxIndex
Jae DontSkip ;Above MaxIndex -> exit
Push Ax ;Save in HSGIndex
Push Dx
Call GetCurTrack ;Get current track
Pop Word Ptr [HSGIndex+2] ;Save...
Pop Word Ptr [HSGIndex]
Push Cx ;Save current track
Call GetCurTrackFromIndex ;Get track to jump to
Pop Ax ;Restore current track
Cmp Al,Cl ;Jump within same track ?
Jz Skip ;Yes -> skip
Call IsAudioTrack ;Is that track an audio track
Jnz DontSkip ;No -> don't skip
Skip:
Call PlayCD ;Jump 10 seconds forward
DontSkip:
Ret
Endp
Backup10Sex Proc Near ;Jump 10 seconds backward
Call GetCDInfo ;Get CD info
Call SaveCurPos ;Save current position
Mov Ax,Word Ptr [HSGIndex] ;Check if sector is ok...
Mov Dx,Word Ptr [HSGIndex+2]
Or Dx,Dx ;Check if above frame #750
Jnz OKToSubstract
Cmp Ax,750
Jb DontBackup ;Not above -> exit
OKToSubstract:
Sub Ax,750 ;Substract 750 frames=10 secs
Sbb Dx,0
Mov Si,Offset MinIndex
Call CompareIndexes ;Compare to MinIndex
Jbe DontBackup ;Below MinIndex -> exit
Push Ax ;Save in HSGIndex
Push Dx
Call GetCurTrack ;Get current track
Pop Word Ptr [HSGIndex+2] ;Save...
Pop Word Ptr [HSGIndex]
Push Cx ;Save current track
Call GetCurTrackFromIndex ;Get track to jump to
Pop Ax ;Restore current track
Cmp Al,Cl ;Jump within same track ?
Jz Backup ;Yes -> backup
Call IsAudioTrack ;Is that track an audio track
Jnz DontBackup ;No -> don't backup
Backup:
Call PlayCD ;Jump 10 seconds backwards
DontBackup:
Ret
Endp
IncreaseVolume Proc Near ;Input: CL=Channel bits
Push Cx ;Save channel bits
Call GetVolumeSettings ;Get current settings
Pop Cx ;Restore channel bits
Mov Bx,Offset IOCTLBuffer+2 ;First offset in buffer
IncVolumeLoop:
Or Cl,Cl ;Is CL 0 ?
Jz ExitIncVolumeLoop ;Yes -> exit
Test Cl,1 ;Increase this channel ?
Jz NextChannelCheckInc ;No -> next channel
Cmp Byte Ptr [Bx],256-VolumeSteps ;Addition allowed ?
Jae VolumeToMax ;No -> simply set to max
Add Byte Ptr [Bx],VolumeSteps ;Add...
Jmp NextChannelCheckInc
VolumeToMax:
Mov Byte Ptr [Bx],255 ;Set volume to maximum
NextChannelCheckInc:
Shr Cl,1 ;Check next channel
Add Bx,2 ;2 bytes further in buffer
Jmp IncVolumeLoop ;Next loop
ExitIncVolumeLoop:
Call SetVolumeSettings ;And write the settings
Ret
Endp
DecreaseVolume Proc Near ;Input: CL=Channel bits
Push Cx ;Save channel bits
Call GetVolumeSettings ;Get current settings
Pop Cx ;Restore channel bits
Mov Bx,Offset IOCTLBuffer+2 ;First offset in buffer
DecVolumeLoop:
Or Cl,Cl ;Is CL 0 ?
Jz ExitDecVolumeLoop ;Yes -> exit
Test Cl,1 ;Decrease this channel ?
Jz NextChannelCheckDec ;No -> next channel
Cmp Byte Ptr [Bx],VolumeSteps-1 ;Substraction allowed ?
Jbe VolumeToMin ;No -> simply set to min
Sub Byte Ptr [Bx],VolumeSteps ;Substract...
Jmp NextChannelCheckDec
VolumeToMin:
Mov Byte Ptr [IOCTLBuffer+Bx],0 ;Set volume to minimum
NextChannelCheckDec:
Shr Cl,1 ;Check next channel
Add Bx,2 ;2 bytes further in buffer
Jmp DecVolumeLoop ;Next loop
ExitDecVolumeLoop:
Call SetVolumeSettings ;And write the settings
Ret
Endp
StopRequest Proc Near ;Called upon F11 press
Call CDLoaded ;Check if CD loaded
Jnz ExitStopRequest ;No -> exit
Call StopCD ;Stop playing
ExitStopRequest:
Ret
Endp
PlayRequest Proc Near ;Called upon F12
Call CDLoaded ;Check if CD loaded
Jnz LoadAndPlay ;No -> load and start playing
TryToGetInfoAgain:
Call GetCDInfo ;Get CD info
Test [IOCTLStatus],ErrorBit ;Error ?
Jnz TryToGetInfoAgain ;Yes -> try again
Test [IOCTLStatus],DeviceBusy ;Already playing ?
Jnz RestartTrack ;Yes -> restart track
Cmp Word Ptr [StartAddress],0 ;Restart CD ?
Jnz ContinuePlay ;No -> continue play
Cmp Word Ptr [StartAddress+2],0 ;Restart CD ?
Jnz ContinuePlay ;No -> continue play
Jmp NotReadyYet ;Start playing
ContinuePlay:
Call GetCurTrack ;Get current track
Or Cl,Cl ;Even before MinTrack ?
Jz StartAtFirstTrack ;Yes -> restart CD
Mov Ax,Word Ptr [StartAddress] ;Copy startaddress into
Mov Word Ptr [HSGIndex],Ax ; HSGIndex
Mov Ax,Word Ptr [StartAddress+2]
Mov Word Ptr [HSGIndex+2],Ax
Call PlayCD ;Play from index
Jmp ExitPlayRequest
LoadAndPlay:
Call LoadCD ;Load CD
NotReadyYet:
Call GetCDInfo ;Get CD info
Test [IOCTLStatus],ErrorBit ;Error ?
Jnz NotReadyYet ;Yes -> try again
StartAtFirstTrack:
Sub Cl,Cl ;Search for first audio track
Call GetNextAudioTrack ;Search...
Or Cl,Cl ;Audio track found ?
Jz ExitPlayRequest ;No -> exit
Call PlayFromTrack ;Play from track...
Jmp ExitPlayRequest
RestartTrack:
Call GetCurTrack ;Get current track
Call PlayFromTrack ;Play from track...
ExitPlayRequest:
Ret
Endp
EjectRequest Proc Near ;Called upon SHIFT-F11
Call UnlockDoor ;Unlock drive door
Call EjectCD ;Eject disc
Ret
Endp
LoadRequest Proc Near ;Called upon SHIFT-F12
Call LoadCD ;Load CD
Ret
Endp
PrevRequest Proc Near ;Called upon CTRL-F11
Call PrevTrack ;Jump to previous track
Ret
Endp
NextRequest Proc Near ;Called upon CTRL-F12
Call NextTrack ;Jump to next track
Ret
Endp
BackRequest Proc Near ;Called upon ALT-F11
Call Backup10Sex ;Jump 10 secs backwards
Ret
Endp
SkipRequest Proc Near ;Called upon CTRL-F12
Call Skip10Sex ;Jump 10 secs forwards
Ret
Endp
LVUpRequest Proc Near ;Called upon ALT-LSHIFT-'>'
Mov Cl,0101b ;Channels 0 and 2
Call IncreaseVolume ;Increase volume
Ret
Endp
LVDnRequest Proc Near ;Called upon ALT-LSHIFT-'<'
Mov Cl,0101b ;Channels 0 and 2
Call DecreaseVolume ;Decrease volume
Ret
Endp
RVUpRequest Proc Near ;Called upon ALT-RSHIFT-'>'
Mov Cl,1010b ;Channels 1 and 3
Call IncreaseVolume ;Increase volume
Ret
Endp
RVDnRequest Proc Near ;Called upon ALT-RSHIFT-'<'
Mov Cl,1010b ;Channels 1 and 3
Call DecreaseVolume ;Decrease volume
Ret
Endp
LRVURequest Proc Near ;Called upon ALT-'>'
Mov Cl,1111b ;Channels 0, 1, 2 and 3
Call IncreaseVolume ;Increase volume
Ret
Endp
LRVDRequest Proc Near ;Called upon ALT-'<'
Mov Cl,1111b ;Channels 0, 1, 2 and 3
Call DecreaseVolume ;Decrease volume
Ret
Endp
;====---- TSR Variables ----================================================
Busy Db 0 ;Busy flag
;Change these arrays to
;swap/add commands:
RequestNumber Db 01,03,03,03,05,00,00,00 ;Play requests
Db 07,00,00,00,00,00,00,00
VolumeRequest Db 00,00,00,00,00,00,00,00 ;Volume requests
Db 13,11,09,13,00,00,00,00
RequestHandlr Dw Offset StopRequest,Offset PlayRequest ;01+02
Dw Offset EjectRequest,Offset LoadRequest ;03+04
Dw Offset PrevRequest,Offset NextRequest ;05+06
Dw Offset BackRequest,Offset SkipRequest ;07+08
Dw Offset LVDnRequest,Offset LVUpRequest ;09+10
Dw Offset RVDnRequest,Offset RVUpRequest ;11+12
Dw Offset LRVDRequest,Offset LRVURequest ;13+14
OrgIntOfs Dw 0 ;Original Int-Offset
OrgIntSeg Dw 0 ;Original Int-Segment
CDROMDrive Dw 0 ;First CD-ROM drive
;====---- IOCTL Variables ----==============================================
IOCTLBlock: ;Standard IOCTL-block...
IOCTLBlockLen Db 0 ;Block length
DevSubUnit Db 0 ;Device Sub Unit
IOCTLCommand Db 0 ;Command code
IOCTLStatus Dw 0 ;Device status
IOCTLDummies1 Dd 0,0 ;Never used
IOCTLAddMode Db 0 ;0=HSG, 1=Red book
CDStartPlay: ;Start-sector for play
IOCTLTransOfs Dw 0 ; or transfer address
IOCTLTransSeg Dw 0
CDStopPlay: ;Stop-sector for play
IOCTLLen Dw 0 ; or IOCTL length
Dw 0
IOCTLDummies2 Dd 0,0 ;To fill up IOCTL-Block...
IOCTLBuffer Db MaxBlockLen Dup(0) ;Buffer for CD-ROM requests
;====---- CD Play variables ----============================================
HSGIndex Db 0,0,0,0 ;Where PlayCD starts playing
StartAddress Db 0,0,0,0 ;Used to simulate 'pause'
MinIndex Db 0,0,0,0 ;First audio-sector
MaxIndex Db 0,0,0,0 ;Last audio-sector
MinTrack Db 0 ;First track number
MaxTrack Db 0 ;Last track number
;====---- DTCD kept resident up until here ----=============================
EndOfTSR Db 0
;====---- Initialization ----===============================================
.8086 ;No 80286 detected yet...
Initialization:
Mov Ah,9 ;Display opening string
Mov Dx,Offset WelcomeStr
Int 21h
Detect80286:
Pushf ;Standard check for 80286
Pushf
Pop Ax
And Ax,0FFFh
Push Ax
Popf
Pushf
Pop Ax
Popf
And Ax,0F000h
Cmp Ax,0F000h
Jz ThisIsAnXT
CheckInstalled:
Mov Ah,4Fh ;Check if DTCD installed
Mov Bx,'DT'
Mov Cx,'CD'
Int 15h
Cmp Ax,'Yo' ;Acknowledged ?
Jz AlreadyInstalled ;Yes -> exit
Mov Ax,1500h ;Check if CD-ROM installed
Sub Bx,Bx
Int 2Fh
Or Bx,Bx ;More than 0 CD-ROMs ?
Jz NoCDROMInstalled ;No -> exit
Mov [CDROMDrive],Cx ;Save first drive letter
Mov Ax,1501h
Mov Bx,Offset IOCTLBuffer
Int 2Fh ;Get drive info in buffer
Sub Ch,Ch
Mov Cl,[Bx] ;Get sub-unit in CL
Mov [DevSubUnit],Cl ;Save sub-unit number
Add [CDROMDrive],Cx ;Add subunit to drive letter
DetectMSCDEX:
Mov Ax,150Bh ;Check MSCDEX installed
Mov Cx,[CDROMDrive]
Int 2Fh
Cmp Bx,0ADADh ;Acknowledge ?
Jnz NoMSCDEX ;No -> exit
DetectMSCDEX21:
Mov Ax,150Ch ;Check MSCDEX version
Int 2Fh
Cmp Bx,020Ah ;Version 2.10
Jb NotRightMSCDEX ;Before -> exit
InstallTSR:
Mov Ax,3515h ;Get interrupt vector
Int 21h
Mov [OrgIntOfs],Bx ;Save interrupt vector
Mov [OrgIntSeg],Es
Mov Dx,Offset TSR ;Set interrupt vector to TSR
Mov Ax,2515h
Int 21h
Mov Ah,9 ;Display end-string
Mov Dx,Offset TSRInst
Int 21h
Mov Dx,Offset EndOfTSR ;Keep TSR resident
Int 27h ;Terminate and Stay Resident
NoCDROMINstalled:
Mov Dx,Offset NoCDROMStr ;No CD ROM installed
Jmp ErrorExit
AlreadyInstalled:
Mov Dx,Offset AlreadyInst ;DTCD already loaded
Jmp ErrorExit
ThisIsAnXT:
Mov Dx,Offset XTString ;No 80286 found
Jmp ErrorExit
NoMSCDEX:
Mov Dx,Offset NoMSCDEXStr ;No MSCDEX found
Jmp ErrorExit
NotRightMSCDEX:
Mov Dx,Offset WrongMSCDEXSt ;Not correct MSCDEX found
ErrorExit:
Mov Ah,9 ;Display error string
Int 21h
Mov Dx,Offset ExitString
Int 21h
Int 20h ;Exit
;====---- String constants for initialization ----==========================
WelcomeStr Db 'DTown Audio-CD Player 1.01 (TSR Version). Release: 25 January 1994.',13,10,13,10,'$'
NoCDROMStr Db 'No CD-ROM detected$'
AlreadyInst Db 'TSR already installed$'
XTString Db 'This program requires a 80286$'
NoMSCDEXStr Db 'MSCDEX not loaded$'
WrongMSCDEXSt Db 'This program requires MSCDEX 2.1 or higher loaded$'
ExitString Db '. DTCD halted...',13,10,'$'
TSRInst Db 'TSR successfully installed. Read DTCD.DOC for keys...',13,10,'$'
Code Ends
End Start